package com.sduept.nwld.dataserver.util;

import com.sduept.utils.CharacterUtil;
import com.sduept.utils.PingYinUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class CimUtils {
	public static final String regex_feature_breaker = "\\d{4}|\\d{3}[^k,K]";
	public static final String regex_feature_busbar = "\\d{1}";
	public static final String regex_feature_voltage = "\\d{3}|\\d{2}";
	public static final Pattern BREAKER_NAME_PATTERN = Pattern.compile(regex_feature_breaker);
	public static final Pattern BUSBAR_NAME_PATTERN = Pattern.compile(regex_feature_busbar);
	public static final Pattern VOLTAGE_PATTERN = Pattern.compile(regex_feature_voltage);
	
	/**
	 * 线路绝对名称匹配
	 * @param ln1
	 * @param ln2
	 * @return
	 */
	public static boolean lineAbsoluteNameMatching(String ln1,String ln2) {
		if(ln1==null) {
			return false;
		}
		if(ln2==null) {
			return false;
		}
		String tmpl1 = CharacterUtil.convertString(getLineNameOfNw(ln1),line_regex);
		String tmpl2 = CharacterUtil.convertString(getLineNameOfNw(ln2),line_regex);
		return tmpl1.equals(tmpl2);
	}
	/**
	 * 线路名称的匹配
	 * @param ln1
	 * @param ln2
	 * @return
	 */
	public static boolean lineNameMatching(String ln1,String ln2){
		boolean isSame = false;
		String tmpl1 = CharacterUtil.convertString(getLineNameOfNw(ln1),line_regex);
		String tmpl2 = CharacterUtil.convertString(getLineNameOfNw(ln2),line_regex);
		
		if(tmpl1.contains(tmpl2)&&tmpl2.length()>1 || tmpl2.contains(tmpl1)&&tmpl1.length()>1){
			isSame = true;
		} else {
			int len1 = tmpl1.length();
			int len2 = tmpl2.length();
			if(len1>1&&len2>1){
				if(len1==len2) {
					int mlen = CharacterUtil.stringMatching(tmpl1,tmpl2);
					if(mlen >= len1 || mlen >= len2 ){
						isSame =  true;
					}
				}
				else {
					if(isContain(tmpl1, tmpl2)||isContain(tmpl2, tmpl1)) {
						isSame =  true;
					}
				}
			}
		}
//		if(!isSame){
//			String p1 = PingYinUtil.getPingYin(tmpl1);
//			String p2 = PingYinUtil.getPingYin(tmpl2);
//			if(p1.equals(p2)){
//				isSame = true;
//			}
//		}
		return isSame;
	}
	/**
	 * 线路名称的匹配
	 * @param ln1
	 * @param ln2
	 * @return
	 */
	public static boolean lineNameMatching(String ln1,String ln2,boolean macthPinYin){
		boolean isSame = false;
		String tmpl1 = CharacterUtil.convertString(getLineNameOfNw(ln1),line_regex);
		String tmpl2 = CharacterUtil.convertString(getLineNameOfNw(ln2),line_regex);
		
		if(tmpl1.contains(tmpl2)&&tmpl2.length()>1 || tmpl2.contains(tmpl1)&&tmpl1.length()>1){
			isSame = true;
		} else {
			int len1 = tmpl1.length();
			int len2 = tmpl2.length();
			if(len1==len2) {
				int mlen = CharacterUtil.stringMatching(tmpl1,tmpl2);
				if(mlen >= len1 || mlen >= len2 ){
					isSame =  true;
				}
			}else {
				if(isContain(tmpl1, tmpl2)||isContain(tmpl2, tmpl1)) {
					isSame =  true;
				}
			}
		}
		if(macthPinYin && !isSame){
			String p1 = PingYinUtil.getPingYin(tmpl1);
			String p2 = PingYinUtil.getPingYin(tmpl2);
			if(p1.equals(p2)){
				isSame = true;
			}
		}
		return isSame;
	}
	/**
	 * 直流线路的名称匹配 
	 * @param ln1
	 * @param ln2
	 * @return
	 */
	public static boolean dclineNameMatching(String ln1,String ln2){
		boolean isSame = false;
		String tmpl1 = CharacterUtil.convertString(ln1,dcline_regex);
		String tmpl2 = CharacterUtil.convertString(ln2,dcline_regex);
		
		if(tmpl1.contains(tmpl2)&&tmpl2.length()>1 || tmpl2.contains(tmpl1)&&tmpl1.length()>1){
			isSame = true;
		} else {
			int len1 = tmpl1.length();
			int len2 = tmpl2.length();
			if(len1==len2) {
				int mlen = CharacterUtil.stringMatching(tmpl1,tmpl2);
				if(mlen >= len1 || mlen >= len2 ){
					isSame =  true;
				}
			}else {
				if(isContain(tmpl1, tmpl2)||isContain(tmpl2, tmpl1)) {
					isSame =  true;
				}
			}
		}
		return isSame;
	}
	
	public static float getVoltageByString(String str){
		float rtn = 0;
		str = str.toLowerCase();
		int pos = str.indexOf("kv");
		if(pos > 0){
			str = str.substring(0,pos);
		}
		Matcher m = VOLTAGE_PATTERN.matcher(str);
		if (m.find()) {
			String v =  m.group(0);
			//log.info(v);
			try {
				rtn = Float.valueOf(v).floatValue();
			} catch (Exception e) {
			}
		}
		return rtn;
	}
	public static boolean compenNameMatching(String ln1,String ln2){
		String tmpl1 = CharacterUtil.convertString(ln1,line_regex);
		String tmpl2 = CharacterUtil.convertString(ln2,line_regex);
		if(tmpl1.contains(tmpl2) || tmpl2.contains(tmpl1)){
			return true;
		} else {
			
			int len1 = tmpl1.length();
			int len2 = tmpl2.length();
			int mlen = CharacterUtil.stringMatching(tmpl1,tmpl2);
			if(mlen >= len1 || mlen >= len2 ){
				return true;
			}
		}
		return false;
	}
	 public static String[][] line_regex = new String[][]{
			{"\\s*", ""},
			{"//|[0-9]+[-,_]", ""},
			{"//|[0-9]+kV", ""},
			{"//|回$", "线"},
			{"//|丁|IV|iv|Ⅳ|4", "四"},
			{"//|丙|III|iii|Ⅲ|3", "三"},
			{"//|乙|II|ii|Ⅱ|2", "二"},
			{"//|甲|I|i|Ⅰ|1", "一"}
		};
		public static String[][] dcline_regex = new String[][]{
			{"\\s*", ""},
			{"套", ""},
			{"\\、", ""},
			{"//|[A-Z]",""},
			{"//|[0-9]+[-,_]", ""},
			{"//|[0-9]+kV", ""},
			{"//|回$", "线"},
			{"//|丁|IV|iv|Ⅳ|4", "四"},
			{"//|丙|III|iii|Ⅲ|3", "三"},
			{"//|乙|II|ii|Ⅱ|2", "二"},
			{"//|甲|I|i|Ⅰ|1", "一"}
		};
	 public static String[][] station_regex = new String[][]{
		 {"\\(", ""},
		 {"\\)", ""},
		 {"\\s*", ""},
		 {"//|[0-9]+[k,K]+[V,v]", ""},
		 {"//|变$", "站"},
		 {"//|厂$", "站"},
	 };
		public static String[][] power_regex = new String[][]{
			{"\\s*", ""},
			{"//|[0-9]+[-,_]", ""},
			{"//|[0-9]+[k,K]+[v,V]", ""},
			{"//|10|35|220|110|500|800", ""},
			{"//|III|iii|Ⅲ", "3"},
			{"//|II|ii|Ⅱ", "2"},
			{"//|I|i|Ⅰ|1", "1"}
		};
		public static String[][] break_regex = new String[][]{
			{"\\s*", ""},
			{"//|[0-9]{1,3}[-]", ""},
			{"//|[0-9]+[k,K]+[V,v]", ""}
		};
		public static String[][] bus_regex = new String[][]{
			{"\\s*", ""},
//			{"//|[0-9]{1,}[-]", ""},
//			{"//|10|35|220|110|500|800", ""},
			{"//|[k,K]+[v,V]", ""},
			{"//|VIII|viii|Ⅷ", "8"},
			{"//|VII|vii|Ⅶ", "7"},
			{"//|VI|vi|Ⅵ", "6"},
			{"//|V|v|Ⅴ|五", "5"},
			{"//|IV|iv|Ⅳ|四", "4"},
			{"//|III|iii|Ⅲ|三", "3"},
			{"//|II|ii|Ⅱ|二", "2"},
			{"//|I|i|Ⅰ|一", "1"}
		};
	/**
	 * 断路器名称的匹配
	 * @param bn1
	 * @param bn2
	 * @return
	 */
	public static boolean breakerNameMatching(String bn1, String bn2){
		
		if(bn1.indexOf("kV") != -1){
			bn1 = bn1.substring(bn1.indexOf("kV"), bn1.length());
		}
		if(bn1.indexOf("kv") != -1){
			bn1 = bn1.substring(bn1.indexOf("kv"), bn1.length());
		}
		if(bn1.indexOf("Kv") != -1){
			bn1 = bn1.substring(bn1.indexOf("Kv"), bn1.length());
		}
		if(bn1.indexOf("KV") != -1){
			bn1 = bn1.substring(bn1.indexOf("KV"), bn1.length());
		}
		if(bn2.indexOf("kV") != -1){
			bn2 = bn2.substring(bn2.indexOf("kV"), bn2.length());
		}
		if(bn2.indexOf("kv") != -1){
			bn2 = bn2.substring(bn2.indexOf("kv"), bn2.length());
		}
		if(bn2.indexOf("Kv") != -1){
			bn2 = bn2.substring(bn2.indexOf("Kv"), bn2.length());
		}
		if(bn2.indexOf("KV") != -1){
			bn2 = bn2.substring(bn2.indexOf("KV"), bn2.length());
		}
		if(CharacterUtil.extractNumber(bn1).equals(CharacterUtil.extractNumber(bn2))){
			return true;
		}
		return false;
	}
	public static boolean breakerNameMatching2(String bn1, String bn2){
		String tmpb1 = getBreakerNameOfNw(bn1);
		String tmpb2 = getBreakerNameOfNw(bn2);
		return tmpb1.equals(tmpb2);
	}
	public static boolean stationNameMatching(String s1, String s2){
		String tmpb1 = getStationNameOfNw(s1);
		String tmpb2 = getStationNameOfNw(s2);
		return tmpb1.equals(tmpb2);
	}
	public static boolean powerTransNameMatching(String bn1, String bn2){
		String tmpb1 = getPowerNameOfNw(bn1);
		String tmpb2 = getPowerNameOfNw(bn2);
		return tmpb1.equals(tmpb2);
	}
	public static String getLineNameOfNw(String lineName){
		int pos = lineName.indexOf("回线");
		if(pos > -1){
			lineName =  lineName.substring(0, pos+1);
		} else {
			pos = lineName.indexOf("线");
			if(pos > -1){
				lineName =  lineName.substring(0, pos+1);
			} else {
				 pos = lineName.indexOf("回");
				 if(pos > -1){
					 lineName = lineName.substring(0,  pos+1);
				 } 
			}
		}
		if(pos > -1)
			lineName = convertString(lineName,line_regex);
		return lineName;
	}
	public static String getStationNameOfNw(String sname){
		sname = convertString(sname,station_regex);
		return sname;
	}
	public static String getBreakerNameOfNw(String name){
		name = convertString(name,break_regex);
		int pos = name.indexOf("断路器");
		if(pos > -1){
			name = name.substring(0, pos);
		} else {
			pos = name.indexOf("开关");
			if(pos > -1){
				name = name.substring(0,  pos);
			} 
		}
		Matcher m = BREAKER_NAME_PATTERN.matcher(name);
		if (m.find()) {
			return m.group(0);
		} else if(pos > -1)
			name = convertString(name,break_regex);
		return name;
	}
	public static String getPowerNameOfNw(String name){
		int pos = name.indexOf("变");
		if(pos>-1){
			name=name.substring(0,pos+1);
		}
		name = convertString(name,power_regex);
		Matcher m = BUSBAR_NAME_PATTERN.matcher(name);
		if (m.find()) {
			return m.group(0);
		}
		return name;
	}
	public static String getHydroName(String name){
		int pos = name.indexOf("电机");
		if(pos>-1){
			name=name.substring(0, pos);
		}
		return name;
	}
	public static String getBusNameOfNw(String name,boolean isSign){
		if(isSign){
			name=name.replaceAll("[0-9]{1,}[-_]", "");
		}
//		int pos = name.indexOf("M");
//		if(pos > -1){
//			name = name.substring(0, pos+1);
//		} else {
//			pos = name.indexOf("母");
//			if(pos > -1){
//				name = name.substring(0,  pos+1);
//			} 
//		}
		name = convertString(name,bus_regex);
		name=name.replaceAll("[^\\d]", "");
//		Matcher m = BUSBAR_NAME_PATTERN.matcher(name);
//		if (m.find()) {
//			return m.group(0);
//		}
		return name;
	}
	/**
	 * 获取母线名称，只返回单个数字，如500kV母线1M 会返回 1
	 * @param name
	 * @return
	 */
	public static String getBusNameOfNwSingle(String name){
		name = name.toLowerCase();
		int pos = name.indexOf("kv");
		if(pos > 0){
			name = name.substring(pos+2,name.length());
		}
//		pos = name.indexOf("M");
//		if(pos > -1){
//			name = name.substring(0, pos+1);
//		} else {
//			pos = name.indexOf("母");
//			if(pos > -1){
//				name = name.substring(0,  pos+1);
//			} 
//		}
		name = convertString(name,bus_regex);
		name=name.replaceAll("[^\\d]", "");
//		Matcher m = BUSBAR_NAME_PATTERN.matcher(name);
//		if (m.find()) {
//			return m.group(0);
//		}
		return name;
	}
	public static String getCompenName(String name){
		int pos = name.indexOf("抗");
		if(pos>-1){
			name=name.substring(0,pos-1);
			name=name.replaceAll("#", "");
			name=name.replaceAll("＃", "");
		}
		name=convertString(name, line_regex);
		return name;
	}
	 public static String convertString(String sourceStr, String[][] source_regex){
			String rtn = sourceStr;
			for( String[] et : source_regex){
				rtn = rtn.replaceAll(et[0],et[1]);
			}
			return rtn;
		}
	/**
	 * 母线名称的匹配(包含电压等级),500kV母线1M 会匹配5001
	 * @param bu1
	 * @param bu2
	 * @return
	 */
	public static boolean busNameMatching(String bu1, String bu2){
		String tmb1 = getBusNameOfNw(bu1, false);
		String tmb2 = getBusNameOfNw(bu2, false);
		return tmb1.equals(tmb2);
	}
	/**
	 * 母线名称的匹配(不包含电压等级)500kV母线1M 会匹配1
	 * @param bu1
	 * @param bu2
	 * @return
	 */
	public static boolean busNameSingleMatching(String bu1, String bu2){
		String tmb1 = getBusNameOfNwSingle(bu1);
		String tmb2 = getBusNameOfNwSingle(bu2);
		return tmb1.equals(tmb2);
	}
	
	public static String[][] bus_regex_pro = new String[][]{
		{"\\s*", ""},
		{"//|[-,_]", ""},
		{"//|[k,K]+[v,V]", ""},
		{"//|III|iii|Ⅲ", "3"},
		{"//|II|ii|Ⅱ", "2"},
		{"//|I|i|Ⅰ|1", "1"}
	};
	public static String getBusNameByProName(String name){
		if(name.contains("M")){
			int pos = name.indexOf("M");
			name=name.substring(0, pos+1);
		}else if(name.contains("母")){
			int pos = name.indexOf("母");
			name=name.substring(0, pos+1);
		}
		name =CharacterUtil.convertString(name,bus_regex_pro);
		name=name.replaceAll("[^\\d]", "");
		return name;
		
	}
	public static String getUnitStringByProName(String name){
		if(name.contains("发")){
			name=name.substring(0, name.indexOf("发")+1);
		}else if(name.contains("变")){
			name=name.substring(0, name.indexOf("变")+1);
		}else if(name.contains("机")){
			name=name.substring(0, name.indexOf("机")+1);
		}else if(name.contains("柜")){
			name=name.substring(0, name.indexOf("柜")+1);
		}
		return name;
	}
	public static boolean powerNameMatching(String power1,String power2){
		String substr1 = CharacterUtil.convertString(power1,power_regex).replaceAll("[^\\d]", "");//替换
		String substr2 = CharacterUtil.convertString(power2,power_regex).replaceAll("[^\\d]", "");
		if(substr1.equals(substr2)){
			return true;
		}else{
			return false;
		}
	}
	public static boolean hyDroNameMatching(String hydro1,String hydro2){
		String substr1 =hydro1.replaceAll("[^\\d]", ""); //替换
		String substr2 = hydro2.replaceAll("[^\\d]", "");
		if(substr1.equals(substr2)){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 字符串截去kV
	 * @param bn1
	 * @param bn2
	 * @return
	 */
	public static String convertKV(String con){
		
		if(con.indexOf("kV") != -1){
			con = con.substring(con.indexOf("kV"), con.length());
		}
		if(con.indexOf("kv") != -1){
			con = con.substring(con.indexOf("kv"), con.length());
		}
		if(con.indexOf("Kv") != -1){
			con = con.substring(con.indexOf("Kv"), con.length());
		}
		if(con.indexOf("KV") != -1){
			con = con.substring(con.indexOf("KV"), con.length());
		}
		return con;
	}
	
	private static double EARTH_RADIUS = 6378.137;

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}
	/**
	 * 通过经纬度获取距离(单位：米)
	 * 
	 * @param lng1
	 * @param lat1
	 * @param lng2
	 * @param lat2
	 * @return
	 */
	public static double getDistance( double lng1,double lat1,
			double lng2 ,double lat2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radLat1) * Math.cos(radLat2)
				* Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = Math.round(s * 10000d) / 10000d;
		s = s * 1000;
		return s;
	}
	
	/**
	 * 计算点到线的距离
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param x0
	 * @param y0
	 * @return
	 */
	public static double pointToLine(double x1, double y1, double x2, double y2, double x0, double y0) {
        double space = 0d;
        double a, b, c;
        a = getDistance(x1, y1, x2, y2);// 线段的长度
        b = getDistance(x1, y1, x0, y0);// (x1,y1)到点的距离
        c = getDistance(x2, y2, x0, y0);// (x2,y2)到点的距离
        if (c <= 0.000001 || b <= 0.000001) {
           space = 0;
           return space;
        }
        if (a <= 0.000001) {
           space = b;
           return space;
        }
        if (c * c >= a * a + b * b) {
           space = b;
           return space;
        }
        if (b * b >= a * a + c * c) {
           space = c;
           return space;
        }
        double p = (a + b + c) / 2;// 半周长
        double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
        space = 2 * s / a;// 返回点到线的距离（利用三角形面积公式求高）
        return space;
    }
	public static float getStandVoltagelevel(String s){
		s=s.replaceAll("[^.^\\d]", "");
		float f=Float.parseFloat(s);
		if(f>0&&f<=0.4){
			return (float) 0.4;
		}else if(f>=6&&f<7){
			return (float) 6.6;
		}else if(f>=10&&f<11){
			return (float)10;
		}else if(f>34&&f<=37){
			return (float)35;
		}else if(f>=66&& f<67){
			return (float)66;
		}else if(f>109&&f<120){
			return (float)110;
		}else if(f>209&&f<=230){
			return (float)220;
		}else if(f>345&&f<355){
			return (float)350;
		}else if(f>=500&&f<=525){
			return (float)500;
		}else if(f>=750&&f<850){
			return (float)800;
		}else{
			return f;
		}
	}
	public static float getStandVoltagelevel(float f){
		if(f>0&&f<=0.4){
			return (float) 0.4;
		}else if(f>=6&&f<7){
			return (float) 6.6;
		}else if(f>=10&&f<11){
			return (float)10;
		}else if(f>34&&f<=37){
			return (float)35;
		}else if(f>=66&& f<67){
			return (float)66;
		}else if(f>109&&f<120){
			return (float)110;
		}else if(f>209&&f<=230){
			return (float)220;
		}else if(f>345&&f<355){
			return (float)350;
		}else if(f>=500&&f<=525){
			return (float)500;
		}else if(f>=750&&f<850){
			return (float)800;
		}else{
			return f;
		}
	}
	/**
	 * 判断一个string是否是另一个string的缩写
	 * 方法适用于判断：是否是变电站的缩写/是否是线路名称的缩写（交流或者直流）
	 * string 的长度须大于1 否则返回false
	 * update 20180829方法重写
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static  boolean isContain(String s1,String s2){
		if (StringUtils.isEmpty(s1) || StringUtils.isEmpty(s2)) {
			return false;
		}
		if(s1.length()==1||s2.length()==1){
			return false;
		}
		if(s1.length() == s2.length()){
			return s1.equals(s2);
		}
		String longStr = "";
		String shortStr = "";
		if (s1.length() > s2.length()) {
			longStr = s1;
			shortStr = s2;
		} else  {
			longStr = s2;
			shortStr = s1;
		} 
		char[] stringArr = shortStr.toCharArray();
		for (int i = 0; i < stringArr.length; i++) {
			String sign = String.valueOf(stringArr[i]);
			if (longStr.contains(sign)) {
				longStr = longStr.substring(longStr.indexOf(sign) + 1);
			} else {
				return false;
			}
		}
		return true;
	}
	/**
	 * 判断两个变电站是否一样，包括 简称的情况 
	 * @param s1
	 * @param s2
	 * @param isContain 是否互相包含
	 * @return
	 */
	public static boolean stationNameMatching(String s1, String s2,boolean isContain){
		String tmpb1 = getStationNameOfNw(s1);
		String tmpb2 = getStationNameOfNw(s2);
		boolean a=tmpb1.equals(tmpb2);
		if(a) {
			return true;
		}
		if(isContain) {
			boolean b=isContain(tmpb1, tmpb2);
			boolean c=isContain(tmpb2, tmpb1);
			return a|b|c;
		}
		return a;
	} 
	
	/**
	 * 截取kV和前边的地区（如：广东500kV鹏深乙线，截取后为鹏深乙线）
	 * @param str
	 * @return
	 */
	public static String convertKVAndRegion(String str) {
		Pattern pattern = Pattern.compile("(?i)([0-9]+)kV");//(?i)忽略大小写
		Matcher m = pattern.matcher(str);
		while (m.find()) {
			str = str.substring(m.end());
		}
		return str;
	}
	
	public static void main(String[] args) {
		log.info(convertKVAndRegion("广东500KV鹏深乙线"));
	}
	
}
